package com.hn.zhijian.system.rsasdk;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA签名验签类
 * 
 * @author shaohai.Liu
 * @date 2017-8-7
 * @version 0.0.1
 */
public class RSASignUtils extends AbstractSecurity {
	/**
	 * 工具类实例
	 */
	private static final RSASignUtils INSTANCE = new RSASignUtils();

	/**
	 * 签名算法
	 */
	public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

	/**
	 * 签名算法
	 */
	public static final String SIGN_SHA2 = "SHA256WithRSA";

	/**
	 * 构造方法
	 */
	private RSASignUtils() {
		super();
	}

	/**
	 * 获取实例
	 * 
	 * @return
	 */
	public static final RSASignUtils getInstance() {
		return INSTANCE;
	}

	/**
	 * RSA签名
	 * 
	 * @param content
	 *            待签名数据
	 * @param privateKey
	 *            商户私钥
	 * @param encode
	 *            字符集编码
	 * @return 签名值
	 * @throws SecurityException
	 *             加解密异常
	 */
	public String sign(String content, String privateKey, String encode) throws SecurityException {
		try {
			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(decode(privateKey));

			KeyFactory keyf = KeyFactory.getInstance("RSA");
			PrivateKey priKey = keyf.generatePrivate(priPKCS8);

			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

			signature.initSign(priKey);
			signature.update(content.getBytes(encode));

			byte[] signed = signature.sign();

			return new String(encode(signed));
		} catch (Exception e) {
			throw new SecurityException(e);
		}
	}

	/**
	 * 数字签名
	 * 
	 * @param content
	 *            签名内容
	 * @param privateKey
	 *            私钥
	 * @return 签名串
	 * @throws SecurityException
	 *             加解密异常
	 */
	public String sign(String content, String privateKey) throws SecurityException {
		try {
			PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(decode(privateKey));
			KeyFactory keyf = KeyFactory.getInstance("RSA");
			PrivateKey priKey = keyf.generatePrivate(priPKCS8);
			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
			signature.initSign(priKey);
			signature.update(content.getBytes());
			byte[] signed = signature.sign();

			return new String(encode(signed));
		} catch (Exception e) {
			throw new SecurityException(e);
		}
	}

	/**
	 * RSA验签名检查
	 * 
	 * @param content
	 *            待签名数据
	 * @param sign
	 *            签名值
	 * @param publicKey
	 *            分配给开发商公钥
	 * @param encode
	 *            字符集编码
	 * @return 布尔值
	 * @throws SecurityException
	 *             加解密异常
	 */
	public boolean doCheck(String content, String sign, String publicKey, String encode) throws SecurityException {
		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			byte[] encodedKey = decode(publicKey);
			PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

			signature.initVerify(pubKey);
			signature.update(content.getBytes(encode));

			boolean bverify = signature.verify(decode(sign));
			return bverify;

		} catch (Exception e) {
			throw new SecurityException(e);
		}
	}

	/**
	 * RSA验签名检查
	 * 
	 * @param content
	 *            待签名数据
	 * @param sign
	 *            签名值
	 * @param publicKey
	 *            分配给开发商公钥
	 * @param encode
	 *            字符集编码
	 * @return 布尔值
	 * @throws SecurityException
	 *             加解密异常
	 */
	public boolean doCheckRsa2(String content, String sign, String publicKey, String encode) throws SecurityException {
		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			byte[] encodedKey = decode(publicKey);
			PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

			java.security.Signature signature = java.security.Signature.getInstance(SIGN_SHA2);

			signature.initVerify(pubKey);
			signature.update(content.getBytes(encode));

			boolean bverify = signature.verify(decode(sign));
			return bverify;

		} catch (Exception e) {
			throw new SecurityException(e);
		}
	}

	/**
	 * RSA验证数字签名
	 * 
	 * @param content
	 *            签名内容
	 * @param sign
	 *            签名
	 * @param publicKey
	 *            公钥
	 * @return 布尔值
	 * @throws SecurityException
	 *             加解密异常
	 */
	public boolean doCheck(String content, String sign, String publicKey) throws SecurityException {
		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			byte[] encodedKey = decode(publicKey);

			PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

			java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

			signature.initVerify(pubKey);
			signature.update(content.getBytes());

			boolean bverify = signature.verify(decode(sign));

			return bverify;
		} catch (Exception e) {
			throw new SecurityException(e);
		}
	}
}
